package com.byq.mm.common.engine;


import org.jivesoftware.smack.ConnectionConfiguration;

import org.jivesoftware.smack.SASLAuthentication;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.filter.StanzaTypeFilter;
import org.jivesoftware.smack.packet.Message;

import org.jivesoftware.smack.packet.Presence;
import org.jivesoftware.smack.packet.Presence.Mode;

import org.jivesoftware.smack.roster.Roster;
import org.jivesoftware.smack.sasl.provided.SASLPlainMechanism;
import org.jivesoftware.smack.tcp.XMPPTCPConnection;
import org.jivesoftware.smack.tcp.XMPPTCPConnectionConfiguration;


public class ConnectionManager{
	Environment env;

	public ConnectionManager(Environment e) {
		super();
		env = e;



	}

	private static final String TAG = "AimConnectionService";
	private static final String CERT_DIR = "/system/etc/security/";
	private static final String CERT_FILE = "cacerts.bks";
	private XMPPTCPConnection con;


	public void login(final boolean recoonectIfFailed) {
		Thread task = new Thread() {
			public void run() {
				synclogin(recoonectIfFailed);
			};
		};
		task.start();
	}
	synchronized public void synclogin(final boolean recoonectIfFailed) {
		if(this.isLoggedIn())
			return;

		if(!env.getAccountManager().valid()){
			return;
		}

		ConnectionConfiguration cc = null;
		String host = env.getAccountManager().getHost();
		if (env.getAccountManager().getService() == null || env.getAccountManager().getService().equals("")) {
				return;

		}



		XMPPTCPConnectionConfiguration mConnectConfig = XMPPTCPConnectionConfiguration.builder()
				.setServiceName("xmpp.jp")
				.setHost("xmpp.jp")
				.setPort(5222)

				.setUsernameAndPassword("myhome" , "13311509083")
				//.setSecurityMode( ConnectionConfiguration.SecurityMode. disabled)
				.setCompressionEnabled(false).build();
		//配置授权信息
		SASLAuthentication.registerSASLMechanism(new SASLPlainMechanism());
		//Create a comnection to the igniterealtime.org XMPP server
		con = new XMPPTCPConnection(mConnectConfig);


		env.getEventCenter().notifyLoginStart();
				try {
					con.connect();
					con.login();


				} catch (Exception xe) {
					if(recoonectIfFailed){
						delayedReconnect(xe);
					}
					env.getEventCenter().notifyLoginFail(xe);

					return;
				}

				con.addAsyncStanzaListener(env.getListenerManager().getMessageListener(), StanzaTypeFilter.MESSAGE);
				con.addAsyncStanzaListener(env.getListenerManager().getPresenceListener(),StanzaTypeFilter.PRESENCE);

				con.addConnectionListener(env.getListenerManager().getConnectionListener());



				try {
					Roster roster = Roster.getInstanceFor(con);

					Thread.sleep(1000); // let the roster do its job
					//env.getLiteStore().saveRoster(con.getRoster());

					roster.addRosterListener(env.getListenerManager().getRosterListener());
					roster.addRosterListener(env.getListenerManager().getRosterListener());
;

					setPresenceMode(null,Presence.Mode.available);



				} catch (Exception e) {
					e.printStackTrace();
				}

				env.getEventCenter().notifyLoginSuccess();

				env.getEventCenter().notifyPresenceChange();


	}

	void delayedReconnect(Exception e){
		  env.getEventCenter().notifyConnectionClosedOnError(e);
	}


	public void logout() {
		new Thread() {
			public void run() {
				if (con != null) {

					env.getEventCenter().notifyLogout();
				}
			}
		}.start();

	}

	public void setPresenceMode(final String msg, final Mode mode) {
		if(!this.isLoggedIn())
			return;
		new Thread() {
			public void run() {
				if (con.getUser() != null) {
					Presence presence =  new Presence(Presence.Type.available);
					presence.setStatus(msg);
					presence.setMode(mode);

                    try {
                        con.sendStanza(presence);
                    } catch (SmackException.NotConnectedException e) {
                        throw new RuntimeException(e);
                    }
                }
			}
		}.start();
	}

	public void pushMessage(String message) {
		env.getLiteStore().pushMessage(message);
		Presence.Mode mode = getCurrentMode();
		setPresenceMode(message, mode);
	}
	Presence.Mode getCurrentMode(){
		return Presence.Mode.available;
	}

	
	public void sendMessagePacket(String user, String message) {
        final Message msg = new Message(user, Message.Type.chat);

		msg.setBody(message);


		new Thread() {
			@Override
			public void run() {
				if (con != null && con.getUser() != null) {

                    try {
                        con.sendStanza(msg);
                    } catch (SmackException.NotConnectedException e) {
                        throw new RuntimeException(e);
                    }

                    env.getLiteStore().logOutgoingMessage(msg.getBody(), msg.getTo().toString(),
							con.getUser().toString());
				}
			}
		}.start();
	}

	public void updateRoster() {
		new Thread() {
			public void run() {
				if (con != null && con.getUser() != null) {
					Roster roster = Roster.getInstanceFor(con);
				}
			}
		}.start();

	}

	public boolean isLoggedIn() {
		if (con != null && con.getUser() != null && con.isConnected()) {
			return true;
		}
		return false;
	}

	public XMPPConnection getConnection() {
		// TODO Auto-generated method stub
		return con;
	}

}
